package edu.cmsc611.textsimulator;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Scanner;
//import java.awt.Button;
import java.util.Vector;

public class SimulatorText {

	/**
	 * The stages interface object
	 * @see		Stages
	 */
	public Stages stg = new Stages();
	/**
	 * The listboxes interface object.
	 * @see		ListBoxes
	 */
	public DispInfo lb = new DispInfo();
	/**
	 * The help object.
	 * @see        Help
	 */
	//public Help theHelp;
	/**
	 * The vector that holds the instruction objects.
	 * @see		Instruction
	 */
	public static Vector<Instruction> instr = new Vector<Instruction>();
	/**
	 * The simulator object.
	 * @see        CopyOfSimulator
	 */
	public static CopyOfSimulator sim;
	/**
	 * Booleans used to determine if the user has stepped or
	 * added an instruction.  These are used internally
	 * for dis/enabling buttons in the UI.
	 */
	private boolean stepped, instrAdded;
	/**
	 * Integer that keeps track of number of cycles in the current execution.
	 */
	public int numCycles = 1;
	/**
	 * Float that keeps track of the cycles per instruction.
	 */
	public double CPI = 0.0;


	static OutputChart chart=null;
	/**
	 * The main method provides initializations for the application.
	 */
	public static void main(String[] args)
	{
		FileManage files=FileManage.getInstance();
		String instructionFile="input.txt";
		String configFile="config.txt";
		String regFile="reg.txt";
		String dataFile="data.txt";
		String resultFile="result.txt";
		String sampleResult="";
		String root=".";
		String path=getCannonicalPath();
		path=path+File.separator;
		if(args.length<5)
		{
			System.out.println("Please provide the system with 5 files register, data, config, instruction and result");
			System.exit(1);
		}
		else
		{
			
			regFile=path+args[0].toString();
			dataFile=path+args[1].toString();
			configFile=path+args[2].toString();
			instructionFile=path+args[3].toString();
			resultFile=path+args[4].toString();
			
			/*isFileExists(regFile);
			isFileExists(dataFile);
			isFileExists(configFile);
			isFileExists(instructionFile);
			isFileExists(resultFile);*/
			
			System.out.println("Usange: "+ regFile +" "+dataFile+ " "+ configFile+" "+instructionFile+" "+ resultFile);
			/**
			 * Store filename to singleton class
			 */
			files.setInstructionFile(instructionFile);
			files.setRegisterFile(regFile);
			files.setConfigurationFile(configFile);
			files.setDataFile(dataFile);
			files.setResutlFile(resultFile);
			
			
		}
		if(args.length>5)
		{
			sampleResult=path+args[5];
			isFileExists(sampleResult);
			files.setSampleResultFile(sampleResult);
		}
		
		ReadInput rinput=new ReadInput();
		rinput.readInstructionFromFile(files.getInstructionFile());
		instr=rinput.getInstructions();

		rinput.readConfigurationofSystem(files.getConfigurationFile());
		chart=OutputChart.getInstance();
		//OutputChart chart=new OutputChart();
		chart.createChart(instr.size());
		rinput.readData(files.getDataFile());
		rinput.readRegisterInitialvalue(files.getRegisterFile());
		//System.out.println(instr);

		SimulatorText simt=new SimulatorText();
		simt.init();
		simt.simulatorStep();

		/*
		 * Reading input finished
		 */
		//System.out.print(simt.numCycles);
		OutputChart table=OutputChart.getInstance();
		table.printChart(true,true);

	}
	public static String getCannonicalPath() {
		File currentDirectory = new File(new File(".").getAbsolutePath());
	    String dir=null;
		try {
			dir=currentDirectory.getCanonicalPath();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return dir;
		//return currentDirectory.getAbsolutePath();
	}
	public static void isFileExists(String filename)
	{
		File f = new File(filename);
		if(f.exists() && !f.isDirectory()) { 
			/* do something */ 
			System.out.println("File:"+filename+" does not exists, please provide real file");
			System.exit(1);}
	}
	public static void compareFile(String file1,String file2)
	{
		
		File fileone = new File(file1);  
        File filetwo= new File(file2);  
          
        Scanner scanner1=null;
		try {
			scanner1 = new Scanner(fileone);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}  
        Scanner scanner2=null;
		try {
			scanner2 = new Scanner(filetwo);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}  

        while (scanner1.hasNextLine() && (scanner2.hasNextLine())) {  
            String line1 = scanner1.nextLine().trim().toLowerCase().replaceAll("\\s","").toLowerCase();  
            String line2 = scanner2.nextLine().trim().toLowerCase().replaceAll("\\s","").toLowerCase();  
               if(line1 == line2){  
                   System.out.println(line1 + "matched");  
          }else
          {
        	  System.out.println(line1+" is not equal "+ line2);
          }
        }  
	}
	private void init()
	{
		sim = new CopyOfSimulator(instr, lb, stg);
	}

	private void simulatorStep()
	{
		while(true)
		{
			if(SimulatorRun())
				break;

		}
	}
	public boolean SimulatorRun()
	{
		String temp;
		int tempnum, j = 0;
		boolean done,OK;

		done = false;

		if (!stepped)
		{
			sim.enableForwarding(false);
			//        		sim.enableBP(usr.doBP());

			stepped = true;
		}

		//if (src == usr.step)
			done = sim.step();

			//System.out.println("----------------"+numCycles+"-----------");
			//System.out.println();
		numCycles++;
		stg.nCycles=numCycles;
		j = sim.myWriteBack.getNumberExecutedInstructions();
		stg.nInstr=j;
		if(j>0)
			CPI = (float)numCycles / (float)j;
		stg.cpi=CPI;



        return done;
	}
}
